<?php
namespace app\spadmin\library;
use think\Cache;
use think\Session;
use think\Config;
use think\Cookie;
use think\helper\Str;

use app\common\model\Admin;

class Auth extends \auth\Auth{

    public function __construct()
    {
        parent::__construct();
    }
    /**
     * 获取登录用户的信息
     */
    public function __get($name)
    {
        return Session::get('spadmin_admin.' . $name);
    }
    /**
     * 管理员登录
     *
     * @param string $username 用户名
     * @param string $password 密码
     * @param int    $keeptime 有效时长
     * @return  boolean
     */
    public function login($username, $password, $keeptime = 0)
    {
        $admin = Admin::get(['username' => $username]);
        if (!$admin) {
            $this->setError('登录账号错误');
            return false;
        }
        if ($admin['status'] != '1') {
            $this->setError('登录账号错误');
            return false;
        }
        if ( $admin->loginfailure >= 10 && time() - $admin->updatetime < 3600) {
            $this->setError('登录超限，请1小时后再试');
            return false;
        }
        
        if ($admin->password !== md5(md5($password) . Config::get('auth_key'))) {
            $admin->loginfailure++;
            $admin->save();
            $this->setError('登录密码错误');
            return false;
        }
        $admin->loginfailure = 0;
        $admin->last_login_time = time();
        $admin->last_login_ip = request()->ip();
        $admin->token = Str::uuid();
        $admin->save();
        Session::set("spadmin_admin", $admin->toArray());
        $this->keeplogin($keeptime);
        return true;
    }
    /**
     * 自动登录
     * @return boolean
     */
    public function autologin()
    {
        $keeplogin = Cookie::get('keeplogin');
        if (!$keeplogin) {
            return false;
        }
        list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
        if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
            $admin = Admin::get($id);
            if (!$admin || !$admin->token) {
                return false;
            }
            //token有变更
            if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token . config('token.key'))) {
                return false;
            }
            $ip = request()->ip();
            //IP有变动
            if ($admin->loginip != $ip) {
                return false;
            }
            Session::set("spadmin_admin", $admin->toArray());
            //刷新自动登录的时效
            $this->keeplogin($keeptime);
            return true;
        } else {
            return false;
        }
    }
    /**
     * 检测是否登录
     *
     * @return boolean
     */
    public function isLogin()
    {
        if ($this->logined) {
            return true;
        }
        $admin = Session::get('spadmin_admin');
        if (!$admin) {
            return false;
        }
        //判断是否同一时间同一账号只能在一个地方登录
        $my = Admin::get($admin['id']);
        if (!$my || $my['token'] != $admin['token']) {
            $this->logined = false; //重置登录状态
            Session::delete("spadmin_admin");
            Cookie::delete("spadmin_keeplogin");
            return false;
        }
        //判断管理员IP是否变动
        if (!isset($admin['last_login_ip']) || $admin['last_login_ip'] != request()->ip()) {
            $this->logout();
            return false;
        }
        
        $this->logined = true;
        return true;
    }
    /**
     * 刷新保持登录的Cookie
     *
     * @param int $keeptime
     * @return  boolean
     */
    protected function keeplogin($keeptime = 0)
    {
        if ($keeptime) {
            $expiretime = time() + $keeptime;
            $key = md5(md5($this->id) . md5($keeptime) . md5($expiretime) . $this->token . Config::get('auth_key'));
            $data = [$this->id, $keeptime, $expiretime, $key];
            Cookie::set('spadmin_keeplogin', implode('|', $data), 86400 * 7);
            return true;
        }
        return false;
    }
    /**
     * 退出登录
     */
    public function logout()
    {
        $admin = Admin::get(intval($this->id));
        if ($admin) {
            $admin->token = '';
            $admin->save();
        }
        $this->logined = false; //重置登录状态
        Session::delete('spadmin_admin');
        Cookie::delete("spadmin_keeplogin");
        return true;
    }

    
    public function check($name, $uid = '', $relation = 'or', $mode = 'url')
    {
        $uid = $uid ? $uid : $this->id;
        return parent::check($name, $uid, $relation, $mode);
    }
    /**
     * 获取当前请求的URI
     * @return string
     */
    public function getRequestUri()
    {
        return $this->requestUri;
    }

    /**
     * 设置当前请求的URI
     * @param string $uri
     */
    public function setRequestUri($uri)
    {
        $this->requestUri = $uri;
    }

    public function getGroups($uid = null)
    {
        $uid = is_null($uid) ? $this->id : $uid;
        if(Cache::has('SPADMIN_AUTH_GROUP_LIST_ADMIN_'.$uid)){
            $authgroup =  Cache::get('SPADMIN_AUTH_GROUP_LIST_ADMIN_'.$uid);
        }else{
            $authgroup = parent::getGroups($uid);
            Cache::set('SPADMIN_AUTH_GROUP_LIST_ADMIN_'.$uid,$authgroup);
        }
        return $authgroup;
    }

    public function getRuleList($uid = null)
    {
        $uid = is_null($uid) ? $this->id : $uid;
        if(Cache::has('SPADMIN_AUTH_RULE_LIST_ADMIN_'.$uid)){
            $authrule =  Cache::get('SPADMIN_AUTH_RULE_LIST_ADMIN_'.$uid);
        }else{
            $authrule = parent::getRuleList($uid);
            Cache::set('SPADMIN_AUTH_RULE_LIST_ADMIN_'.$uid,$authrule);
        }

        return $authrule;
    }

    public function getUserInfo($uid = null)
    {
        $uid = is_null($uid) ? $this->id : $uid;

        return $uid != $this->id ? Admin::get(intval($uid)) : Session::get('spadmin_admin');
    }

    public function getRuleIds($uid = null)
    {
        $uid = is_null($uid) ? $this->id : $uid;
        if(Cache::has('SPADMIN_AUTH_RULE_IDS_ADMIN_'.$uid)){
            $authruleids =  Cache::get('SPADMIN_AUTH_RULE_IDS_ADMIN_'.$uid);
        }else{
            $authruleids = parent::getRuleIds($uid);
            Cache::set('SPADMIN_AUTH_RULE_IDS_ADMIN_'.$uid,$authruleids);
        }
        return $authruleids;
    }

    public function isSuperAdmin()
    {
        return in_array('*', $this->getRuleIds()) ? true : false;
    }
    /**
     * 获取菜单
     */
    public function getMenu(){
        $menu = $this->getAllMenu();
        $ruleId = [];
        if(!$this->isSuperAdmin()){
            $ruleId = $this->getRuleIds();
        }
        foreach ($menu as $key => $value) {
            if($value['is_menu']== 0){
                unset($menu[$key]);
            }else{
                if($ruleId && (!in_array($value['id'],$ruleId))){
                    unset($menu[$key]);
                }
            }
        }
        return $menu;
    }
        /**
     * 获取格式化的权限目录树
     */
    public function getMenuContentX(){
        $menu  = $this->getAllMenu();
        return formatTree(listToTree($menu));
    }
    /**
     * 获取格式化的角色组
     */
    public function getGroupContentX(){
        $group = $this->getAllGroup();
        return formatTree(listToTree($group),0,'name');
    }
    /**
     * 所有角色
     */
    public function getAllGroup(){
        if(Cache::has('SPADMIN_AUTH_GROUP_LIST_')){
            $group = Cache::get('SPADMIN_AUTH_GROUP_LIST_');
        }else{
            $group = collection(model('AuthGroup')->where('status',1)->select())->toArray();
            Cache::set('SPADMIN_AUTH_GROUP_LIST_',$group);
        }
        return $group;
    }
    /**
     * 所有权限列表
     */
    public function getAllMenu(){
        if(Cache::has('SPADMIN_AUTH_ROLE_LIST_')){
            $menu = Cache::get('SPADMIN_AUTH_ROLE_LIST_');
        }else{
            $menu = collection(model('AuthRule')->where('status',1)->order('sort desc,id asc')->select())->toArray();
            Cache::set('SPADMIN_AUTH_ROLE_LIST_',$menu);
        }
        return $menu;
    }
    /**
     * 不需要登录的url
     */
    public function getNologinRole(){
        if(Cache::has('SPADMIN_NO_LOGIN_ROLE_')){
            $url = Cache::get('SPADMIN_NO_LOGIN_ROLE_');
        }else{
            $url = model('AuthRule')->where('status',1)->where('is_login',0)->column('url');
            Cache::set('SPADMIN_NO_LOGIN_ROLE_',$url,8640000);
        }
        return $url;
    }
     /**
     * 不需要权限验证的url
     */
    public function getNoAuthRole(){
        if(Cache::has('SPADMIN_NO_AUTH_ROLE_')){
            $url = Cache::get('SPADMIN_NO_AUTH_ROLE_');
        }else{
            $url = model('AuthRule')->where('status',1)->where('is_auth',0)->column('url');
            Cache::set('SPADMIN_NO_AUTH_ROLE_',$url,8640000);
        }
        return $url;
    }

    /**
     * 设置错误信息
     *
     * @param string $error 错误信息
     * @return Auth
     */
    public function setError($error)
    {
        $this->_error = $error;
        return $this;
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->_error ;
    }
}
?>